package com.uduemc.biso.node.web.api.service.impl;

import java.io.File;
import java.io.IOException;

import com.uduemc.biso.core.extities.center.AgentOemNodepage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.uduemc.biso.core.extities.center.Agent;
import com.uduemc.biso.core.extities.pojo.NginxServerConf;
import com.uduemc.biso.core.utils.OSinfoUtil;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.web.api.service.AgentService;
import com.uduemc.biso.node.web.api.service.CenterService;
import com.uduemc.biso.node.web.component.NginxOperate;
import com.uduemc.biso.node.web.component.NginxServerAgent;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class AgentServiceImpl implements AgentService {

	@Autowired
	private CenterService centerServiceImpl;

	@Autowired
	private GlobalProperties globalProperties;

	@Autowired
	private NginxServerAgent nginxServerAgent;

	@Autowired
	private NginxOperate nginxOperate;

	@Override
	public Agent info(long agentId) {
		Agent agent = null;
		try {
			agent = centerServiceImpl.agentInfo(agentId);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return agent;
	}

	@Override
	public boolean bindNodeDomain(Agent agent, String domainName, String universalDomainName) {
		try {
			if (!nginxOperate.boolTest()) {
				log.error("nginx -t 测试失败，错误内容：" + nginxOperate.test());
			}
		} catch (IOException e2) {
			e2.printStackTrace();
			return false;
		}

		Long agentId = agent.getId();
		// 首先清除代理商目录下的所有绑定域名配置文件
		String makeIncludePath = nginxServerAgent.makeIncludePath(agentId);
		if (!FileUtil.isDirectory(makeIncludePath)) {
			return false;
		}
		File[] ls = FileUtil.ls(makeIncludePath);
		if (ArrayUtil.isNotEmpty(ls)) {
			for (File file : ls) {
				if (FileUtil.isFile(file)) {
					FileUtil.del(file);
				}
			}
		}

		if (!bindDomain(agent, domainName)) {
			ls = FileUtil.ls(makeIncludePath);
			if (ArrayUtil.isNotEmpty(ls)) {
				for (File file : ls) {
					if (FileUtil.isFile(file)) {
						FileUtil.del(file);
					}
				}
			}
			return false;
		}

		if (!bindUniversalDomain(agent, universalDomainName)) {
			ls = FileUtil.ls(makeIncludePath);
			if (ArrayUtil.isNotEmpty(ls)) {
				for (File file : ls) {
					if (FileUtil.isFile(file)) {
						FileUtil.del(file);
					}
				}
			}
			return false;
		}

		try {
			if (!nginxOperate.boolTest()) {
				log.error("nginx -t 测试失败，错误内容：" + nginxOperate.test());
			}
		} catch (IOException e2) {
			e2.printStackTrace();
			return false;
		}

		return true;
	}

	@Override
	public boolean bindDomain(Agent agent, String domainName) {
		try {
			if (!nginxOperate.boolTest()) {
				log.error("nginx -t 测试失败，错误内容：" + nginxOperate.test());
			}
		} catch (IOException e2) {
			e2.printStackTrace();
			return false;
		}

		Long agentId = agent.getId();
		NginxServerConf ser = new NginxServerConf();
		ser.setServerName(domainName);

		try {
			String accessLog = "access." + domainName + ".log";
			String errorLog = "error." + domainName + ".log";
			ser.setAccessLog(nginxServerAgent.makeAccessLog(agentId, accessLog)).setErrorLog(nginxServerAgent.makeErrorLog(agentId, errorLog));
		} catch (IOException e1) {
			e1.printStackTrace();
			return false;
		}

		if (OSinfoUtil.isWindows()) {
			ser.setGlobalAccessLog(globalProperties.getNginx().getBase() + File.separator + "logs" + File.separator + "access.log");
			ser.setGlobalErrorLog(globalProperties.getNginx().getBase() + File.separator + "logs" + File.separator + "error.log");
		} else {
			ser.setGlobalAccessLog("/htdocs/nginxlog/access.log");
			ser.setGlobalErrorLog("/htdocs/nginxlog/error.log");
		}

		// 首先代理商绑定节点域名 domain 的文件目录
		try {
			String makeIncludeFile = nginxServerAgent.makeIncludeFile(agentId, domainName);
			if (FileUtil.isFile(makeIncludeFile)) {
				FileUtil.del(makeIncludeFile);
			}
			if (nginxServerAgent.bandleDomain(agent, ser)) {
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public boolean bindUniversalDomain(Agent agent, String universalDomainName) {
		try {
			if (!nginxOperate.boolTest()) {
				log.error("nginx -t 测试失败，错误内容：" + nginxOperate.test());
			}
		} catch (IOException e2) {
			e2.printStackTrace();
			return false;
		}

		if (!StrUtil.startWith(universalDomainName, "*")) {
			return false;
		}

		String[] split = universalDomainName.split("\\.");
		if (!split[0].equals("*")) {
			return false;
		}

		Long agentId = agent.getId();
		NginxServerConf ser = new NginxServerConf();
		ser.setServerName(universalDomainName);

		try {
			String replace = StrUtil.replace(universalDomainName, "*.", "_.");
			String accessLog = "access." + replace + ".log";
			String errorLog = "error." + replace + ".log";
			ser.setAccessLog(nginxServerAgent.makeAccessLog(agentId, accessLog)).setErrorLog(nginxServerAgent.makeErrorLog(agentId, errorLog));
		} catch (IOException e1) {
			e1.printStackTrace();
			return false;
		}

		if (OSinfoUtil.isWindows()) {
			ser.setGlobalAccessLog(globalProperties.getNginx().getBase() + File.separator + "logs" + File.separator + "access.log");
			ser.setGlobalErrorLog(globalProperties.getNginx().getBase() + File.separator + "logs" + File.separator + "error.log");
		} else {
			ser.setGlobalAccessLog("/htdocs/nginxlog/access.log");
			ser.setGlobalErrorLog("/htdocs/nginxlog/error.log");
		}

		// 首先代理商绑定节点域名 domain 的文件目录
		try {
			String makeIncludeFile = nginxServerAgent.makeIncludeFile(agentId, universalDomainName);
			if (FileUtil.isFile(makeIncludeFile)) {
				FileUtil.del(makeIncludeFile);
			}
			if (nginxServerAgent.bandleDomain(agent, ser)) {
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}

	@Override
	public AgentOemNodepage getAgentOemNodepage(long agentId) {
		AgentOemNodepage agentOemNodepage = null;
		try {
			agentOemNodepage = centerServiceImpl.getAgentOemNodepage(agentId);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return agentOemNodepage;
	}
}
